package com.zwh.se.constant_variable_operator;

/**
 * 赋值运算符,也就是常见的"=",它跟我们平时用的等于不是一个东西,java的等于是"=="。
 * 之所以这样子是因为赋值这个动作自然也是需要一个符号来定义的,而前人认为使用=更好理解,因此就这样沿袭下来了。
 *
 * @author yexi
 */
public class AssignmentOperators {
    public static void main(String[] args) {

        int count = 10;//赋值,将10这个常量赋予count这个变量
        System.out.println(count);//此时的count就是10
        count = 20;//将20这个值赋予给count这个变量,这个新的值覆盖了之前的10
        System.out.println(count);//现在就是20了

        //赋值过程中也是可以进行计算的
        count = 10 + 20;//代表着先将10这个常量和20这个常量先计算出来结果30,再赋予给count这个变量
        System.out.println(count);//30

        //计算过程可以使用变量,并且可以重新赋予给自己
        count = count + 20;//代表着先取出count现在的值也就是30和20这个常量先计算出来结果50,再赋予给count这个变量
        System.out.println(count);//50
        //鉴于以上这种写法可读性稍微差了些(只是稍微),因此编译器提供了一些更为方便的写法
        //比如有这些:+= -= *= /= %=   对于这些我们都可以
        count += 10;//等同于count = count + 10;
        System.out.println(count);//60
        //这种通过简化了写法,却能达到相同的效果的语法,我们就可以将之称之为"语法糖",所以以后见到"语法糖"这个词,就可以知道是在说这样写更简便的意思而已
        //当然这种写法也有一种特殊的学名，叫做"扩展赋值运算符(在C/C++中又叫"复合赋值运算符")"
        // 区别：
        // count += 10 ：对于普通人来说，可读性稍微差了点。但是实际上，其编译效率更高，底层会自动进行类型转换。
        // count = count + 10： 可读性好，编译效率低，涉及需要"强制类型转换"的运算时需要手动进行类型转换。
        //    有趣的是"语法糖"的定义是：能够增加程序的可读性，从而减少程序代码出错的机会。
        //    所以跟上面挺矛盾？毕竟是针对程序员而言，+=对程序员确实可能更具可读性。

        //其他的像 -= *= /= %= 同理,就不解释了

        //可以让不同的数据类型之间进行运算,但是如果运算的类型不一样,会自动进行"强制类型转换"(该词汇可以到对应部分进行查阅)
        char c = 'a';
        c += 1;//c = (char)(c+1);
        System.out.println(c);
        byte d = 10;
        //d = d+1;
        d += 1;//d = (byte)(d+1)
        System.out.println(d);

        //TIPS:本拓展内容参考网上博客进行撰写，非原创注意:https://www.cnblogs.com/Brad-Lee/p/5808299.html
        System.out.println("----------------两个变量交换的四种方法----------------");
        // 需求：给定两个数，请交换两个数的值
        int m = 10;
        int n = 20;

        //1、传统方法：
        // 思路:鉴于 = 是个赋值操作,而赋值总得追求一个先后(同时什么的不存在的,计算机不是人),
        // 所以单单两个数来进行交换是必然做不到的,因此可以想到需要有第三个变量来作为中转站
        int tmp = 0; // 申请一个临时空间
        tmp = m; // 把m赋值给tmp
        m = n; // 把n赋值给m
        n = tmp; // 把tmp赋值给n
        System.out.println("m=" + m + " n=" + n);

        //2、可以用两个数求和然后相减的方式进行数据交换,弊端在于如果 x 和 y 的数值过大的话，超出 int 的值会损失精度。
        m = m + n; // m(30) = m(20) + n(10)
        n = m - n; // n(20) = m(30) - n(10)
        m = m - n; // m(10) = m(30) - n(20)
        System.out.println("m=" + m + " n=" + n);

        //3、利用位运算的方式进行数据的交换，利用的思想原理是：一个数异或同一个数两次，结果还是那个数，而且不会超出int范围
        m = m ^ n;
        n = m ^ n; // n = (m ^ n) ^ n
        m = m ^ n; // m = (m ^ n) ^ m
        System.out.println("m=" + m + " n=" + n);

        //4、在打印输出的时候直接交换变量（假交换，只是用来欺骗人的眼睛）
        System.out.println("m=" + n + " n=" + m);

    }
}
